As multi-core processors are becoming widely available, programs are becoming more concurrent to take advantage of the available parallelism. However, increasing concurrency in a program is often non-trivial, due to various potential scalability bottlenecks. One common bottleneck is lock contention, where scalability is limited by many threads waiting to acquire some common lock in order to safely access shared memory.
Various solutions exist for addressing lock contention, each with benefits and drawbacks. Approaches that avoid locks altogether include lock-free data structures (see, e.g., [16]) and transactional memory (TM) [11]. However, writing correct lock-free data structures requires more expertise than can be expected from most programmers, and the semantics of TM may not be suitable in some cases (e.g., if I/O needs to be performed). Making locking more fine-grained can also increase concurrency, but potentially risks introducing subtle race conditions. In the context of Java, the standard java.util.concurrent library (in the sequel abbreviated as j.u.c.) provides a number of data structures and locking constructs that could also be helpful, with their own tradeoffs. With all these options, there is a strong need for tool support to help programmers experiment with different solutions to see what works best in a particular situation.